﻿using System;
using System.Diagnostics;
using System.Reflection;
using System.Text;

namespace AdTech.Snap
{
    /// <summary>
    /// Simple EventLog Writer.
    /// </summary>
    public class EventLogLogger : ILogger
    {
        // Fields
        private readonly string source;
        private readonly Version version;

        // Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="AdTech.Snap.EventLogLogger"/> class.
        /// </summary>
        public EventLogLogger()
        {
            AssemblyName info = Assembly.GetExecutingAssembly().GetName();
            this.source = info.Name;
            this.version = info.Version;
        }

        /// <summary>
        /// Creates a new instance of the <see cref="AdTech.Snap.EventLogLogger"/> class.
        /// </summary>
        public static ILogger Create()
        {
            return new EventLogLogger();
        }

        #region ILogger Members
        /// <summary>
        /// Writes the given message to the EventLog.
        /// </summary>
        /// <param name="message">The message to write to the EventLog.</param>
        /// <param name="type">The <see cref="AdTech.Snap.LogType"/> of the mssage.</param>
        public void Log(string message, LogType type)
        {
            EventLog.WriteEntry(this.source, message, ConvertToEventLogType(type), 666, 1);
        }

        /// <summary>
        /// Reports an unhandled exception to the EventLog with verbose output.
        /// </summary>
        /// <param name="ex">The <see cref="System.Exception"/> that should be logged.</param>
        /// <remarks>The message will be logged with the <see cref="AdTech.Snap.LogType"/> Error.</remarks>
        public void Log(Exception ex)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("An unhandled exception occured in {0} [{1}].", this.source, this.version);
            sb.AppendLine();
            sb.AppendLine("See the exception details for more information:");
            sb.AppendLine(new string('=', 17));
            sb.Append(ex);
            Log(sb.ToString(), LogType.Error);
        }
        #endregion

        /// <summary>
        /// Converts a <see cref="AdTech.Snap.LogType"/> to a <see cref="System.Diagnostics.EventLogEntryType"/>.
        /// </summary>
        /// <param name="type">The <see cref="AdTech.Snap.LogType"/>.</param>
        /// <returns></returns>
        private EventLogEntryType ConvertToEventLogType(LogType type)
        {
            switch (type)
            {
                case LogType.Error: default: return EventLogEntryType.Error;
                case LogType.Information: return EventLogEntryType.Information;
                case LogType.Warning: return EventLogEntryType.Warning;
            }
        }
    }
}
